#-- xmlsimple loads ActiveSupport (again), so we suppress annoying warning messages
verbose, $-v = $-v, nil
require 'xmlsimple'
$-v = verbose

module ActiveMerchant
  module Billing
    module AuthorizeNetCimAPI
      class Request < Base
        alias_method :children_to_xml, :to_xml
  
        self.scalar_attributes = [ [:refId, false, 20] ]

        def submit(gateway)
          return not_valid_response if self.class == Request || !valid?

          @authentication = gateway.authentication
          #puts to_xml
          data = gateway.ssl_post gateway.url, to_xml, 'Content-Type' => 'text/xml'

          parse_response(data, gateway.test?)
        end
  
        def self.request_name
          name = self.to_s[/^.*::(.*)/,1]
          name[0..0] = name[0..0].downcase
          name + 'Request'
        end

        def to_xml(tmp=nil)
          xml = Builder::XmlMarkup.new :indent => 2
          xml.instruct!
          xml.tag! request_name, :xmlns => 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' do
            xml.tag! 'merchantAuthentication' do
              @authentication.to_xml(xml)
            end
            children_to_xml(xml)
          end
    
          xml.target!
        end
  
        def request_name
          self.class.request_name
        end
  
        def parse_data(doc)
          HashWithIndifferentAccess.new(doc)
        end
  
        private
        def not_valid_response
          Response.new(false, 'data is not valid (check errors)', {:data => self}, {})
        end
  
        def parse_response(xml, test=false)
          doc = HashWithIndifferentAccess.new(XmlSimple.xml_in(xml, 'ForceArray' => false)).reject{|k,v| k =~/^xml/}

          messages = doc.delete(:messages)
          refId = doc.delete(:refId)
          success = messages[:resultCode] == 'Ok'
          params = (success ? {:data => parse_data(doc)} : {}).merge :refId => refId
    
          ActiveMerchant::Billing::Response.new(success, messages[:message][:text], params, {:test => test})
        end
      end
    end
  end
end